﻿using Kingdee.BOS;
using Kingdee.BOS.App.Core;
using Kingdee.BOS.App.Data;
using Kingdee.BOS.Contracts;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.CommonFilter;
using Kingdee.BOS.Core.Const;
using Kingdee.BOS.Core.Deploy;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.List;
using Kingdee.BOS.Core.List.PlugIn;
using Kingdee.BOS.Core.ListFilter;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.Core.Metadata.FormElement;
using Kingdee.BOS.Core.Permission;
using Kingdee.BOS.Core.Report;
using Kingdee.BOS.Core.Report.PlugIn;
using Kingdee.BOS.Core.ReportFilter;
using Kingdee.BOS.Core.SqlBuilder;
using Kingdee.BOS.FileServer.Core.Object;
using Kingdee.BOS.FileServer.ProxyService;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Log;
using Kingdee.BOS.Model.ReportFilter;
using Kingdee.BOS.Msg;
using Kingdee.BOS.Orm.DataEntity;
using Kingdee.BOS.Serialization;
using Kingdee.BOS.ServiceHelper;
using Kingdee.BOS.ServiceHelper.Excel;
using Kingdee.BOS.Util;
using Kingdee.BOS.Web;
using Kingdee.BOS.Web.Core;
using Kingdee.BOS.Web.DynamicForm;
using Kingdee.BOS.Web.List;
using Kingdee.BOS.Web.Printing;
using Kingdee.BOS.Web.Report;
using LianKe.BaseData;
using Newtonsoft.Json;
using OfficeOpenXml;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Reflection;
//using System.Runtime.Remoting.Contexts;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using static Kingdee.BOS.App.Core.Validation.EntryEntity.CompositePKValidator.KeyHelper;
using static LianKe.BaseData.BaseParam;

namespace LianKe.LianKeSchedule
{
    public class CreateSchedule : IScheduleService
    {
        public void Run(Context ctx, Schedule schedule)
        {
            ctx.CurrentOrganizationInfo.ID = 1;
            ctx.UserId = 100069;
            if (schedule.Parameters.IsNullOrEmpty())
            {
                return;
            }
            var parameter = JsonConvert.DeserializeObject<ScheduleParameter>(schedule.Parameters);
            try
            {
                NewGetReportData(ctx, parameter);
                //SaveReportData(ctx, parameter);
            }
            catch (Exception ex)
            {
                var errMsg = string.Format("读取报表数据异常:{0}", JsonConvert.SerializeObject(parameter));
                Logger.Error("Jac", errMsg, ex);
            }
        }

        private void NewGetReportData(Context ctx, ScheduleParameter parameter)
        {
            try
            {
                string rptFormId = parameter.RptFormId;
                string rptFilterFormId = parameter.RptFilterFormId;
                string rptFilterSchemeId = parameter.SchemeId;
                //获取相关元数据
                var comFilterMetadata = FormMetaDataCache.GetCachedFilterMetaData(ctx);
                var rptMetadata = FormMetaDataCache.GetCachedFormMetaData(ctx, rptFormId);
                var rptFilterMetadata = FormMetaDataCache.GetCachedFormMetaData(ctx, rptFilterFormId);

                var rptType = rptMetadata.BaseObjectId;
                if (rptType == "BOS_SQLReport")
                {
                    DataTable sqlDt = GetSqlRptData(ctx, rptMetadata, parameter);
                    // 生成 Excel 字节流
                    byte[] excelBytes = DataTableToExcel(sqlDt);
                    // 发送邮件
                    foreach (var mail in parameter.To)
                    {
                        SendEmailWithAttachment(excelBytes, mail, parameter.ScheduleName);
                    }
                }
                else if (rptType == "BOS_MoveSysReport")
                {
                    var reportFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                    var model = new SysReportFilterModel();
                    model.SetContext(ctx, rptFilterMetadata.BusinessInfo, reportFilterServiceProvider);
                    model.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                    model.FilterObject.FilterMetaData = comFilterMetadata;
                    model.InitFieldList(rptMetadata, rptFilterMetadata);
                    model.GetSchemeList();//过滤方案的主键值，可通过该SQL语句查询得到：SELECT * FROM T_BAS_FILTERSCHEME
                    var entity = model.Load(rptFilterSchemeId);
                    var dyn = DeserializeCustomFilter(rptFilterMetadata.BusinessInfo, entity.CustomFilterSetting);
                    model.DataObject = dyn;
                    var filter = model.GetFilterParameter();
                    IRptParams rptParam = new RptParams();
                    rptParam.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                    rptParam.CurrentPosition = 0;//分页账表当前位置
                    rptParam.StartRow = 1;
                    rptParam.EndRow = int.MaxValue;//StartRow和EndRow是报表数据分页的起始行数和截至行数，一般取所有数据，所以EndRow取int最大值。
                    rptParam.FilterParameter = filter;
                    rptParam.FilterFieldInfo = model.FilterFieldInfo;
                    var dic = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);
                    foreach (var itemProp in dyn.DynamicObjectType.Properties)
                    {
                        dic[itemProp.Name] = dyn[itemProp.Name];
                    }
                    rptParam.CustomParams.Add("OpenParameter", dic);
                    MoveReportServiceParameter param = new MoveReportServiceParameter(ctx, rptMetadata.BusinessInfo, Guid.NewGuid().ToString(), rptParam);
                    var movReport = SysReportServiceHelper.GetListAndReportData(param);

                    Dictionary<int, IMoveReport> rtnDIc = new Dictionary<int, IMoveReport>();
                    rtnDIc[0] = movReport;
                    // 获取其他分页
                    if (movReport.ListCount > 1)
                    {
                        for (int i = 1; i < movReport.ListCount; i++)
                        {
                            IMoveReport tmpRpt = GetReportDataNext(ctx, i, rptMetadata.BusinessInfo, rptParam);
                            rtnDIc[i] = tmpRpt;
                        }
                    }

                    List<BaseDataField> baseDataFields = new List<BaseDataField>();
                    List<DateField> dateFields = new List<DateField>();
                    List<ComboField> comboFields = new List<ComboField>();
                    var typeList = rptMetadata.BusinessInfo.Elements;
                    foreach (var type in typeList)
                    {
                        var item = type.GetType();
                        var itemName = type.Name;
                        var itemKey = type.Key;
                        var typeName = item.Name;
                        if (typeName.Equals("BaseDataField"))
                        {
                            baseDataFields.Add(type as BaseDataField);
                        }
                        if (typeName.Equals("DateField"))
                        {
                            dateFields.Add(type as DateField);
                        }
                        if (typeName.Equals("ComboField"))
                        {
                            comboFields.Add(type as ComboField);
                        }
                    }
                    foreach (var rtItem in rtnDIc.Values)
                    {
                        var dataf = rtItem.DataSource;
                        var rh = rptParam.FilterParameter.ColumnInfo;
                        List<string> colList = new List<string>();
                        DataTable newDt = new DataTable();
                        foreach (DataColumn item in dataf.Columns)
                        {
                            foreach (var rname in rh)
                            {
                                if (item.ColumnName.ToUpper() == rname.Key.ToUpper())
                                {
                                    item.Caption = rname.Caption;
                                    colList.Add(item.ColumnName);
                                }
                            }
                        }
                        for (int i = rtItem.DataSource.Columns.Count - 1; i >= 0; i--)
                        {
                            int index = colList.IndexOf(rtItem.DataSource.Columns[i].ColumnName);
                            if (index != -1)
                            {

                            }
                            else
                            {
                                rtItem.DataSource.Columns.Remove(rtItem.DataSource.Columns[i].ColumnName);
                            }
                        }
                    }
                    GetMovNewDt(rtnDIc, baseDataFields, dateFields, comboFields, ctx);
                    rtnDIc = FilteNewDt(rtnDIc, parameter);
                    // 生成 Excel 字节流
                    byte[] excelBytes = DataTableToExcel(rtnDIc);
                    // 发送邮件
                    foreach (var nmail in parameter.To)
                    {
                        SendEmailWithAttachment(excelBytes, nmail, parameter.ScheduleName);
                    }
                }
                else
                {
                    //获取报表过滤方案的构建基础，便于后续模型构建
                    var rptFilterServiceProvider = rptFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
                    var rptModel = new SysReportFilterModel();
                    rptModel.SetContext(ctx, rptFilterMetadata.BusinessInfo, rptFilterServiceProvider);
                    rptModel.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                    rptModel.FilterObject.FilterMetaData = comFilterMetadata;
                    rptModel.InitFieldList(rptMetadata, rptFilterMetadata);
                    rptModel.GetSchemeList();
                    //IsNullOrEmptyOrWhiteSpace()方法须using Kingdee.BOS.Util;
                    if (rptFilterSchemeId.IsNullOrEmptyOrWhiteSpace())
                    {
                        rptModel.LoadDefaultScheme();//加载默认过滤方案
                    }
                    else
                    {
                        rptModel.Load(rptFilterSchemeId);
                    }
                    var filterPara = rptModel.GetFilterParameter();
                    //报表参数
                    IRptParams param = new RptParams();
                    param.FormId = rptFilterMetadata.BusinessInfo.GetForm().Id;
                    param.StartRow = 1;
                    param.EndRow = int.MaxValue;
                    param.FilterParameter = filterPara;
                    param.FilterFieldInfo = rptModel.FilterFieldInfo;
                    param.CustomParams = new Dictionary<string, object>();
                    param.CustomParams.Add("OpenParameter", new Dictionary<string, object>());
                    //报表服务参数，用于查询。
                    var reportServiceParam = new ReportServiceParameter();
                    reportServiceParam.RptFilterParams = param;
                    reportServiceParam.Context = ctx;
                    reportServiceParam.PageId = Guid.NewGuid().ToString();
                    reportServiceParam.BusinessInfo = rptMetadata.BusinessInfo;

                    List<BaseDataField> baseDataFields = new List<BaseDataField>();
                    List<DateField> dateFields = new List<DateField>();
                    List<ComboField> comboFields = new List<ComboField>();
                    var typeList = rptMetadata.BusinessInfo.Elements;
                    foreach (var type in typeList)
                    {
                        var item = type.GetType();
                        var itemName = type.Name;
                        var itemKey = type.Key;
                        var typeName = item.Name;
                        if (typeName.Equals("BaseDataField"))
                        {
                            baseDataFields.Add(type as BaseDataField);
                        }
                        if (typeName.Equals("DateField"))
                        {
                            dateFields.Add(type as DateField);
                        }
                        if (typeName.Equals("ComboField"))
                        {
                            comboFields.Add(type as ComboField);
                        }
                    }
                    //下一句的resutl.DataSource报表数据的DataTable，物理表名是resutl.DataSource.TableName，可将期数据转储到特定表进行二次加工
                    var rh = param.FilterParameter.ColumnInfo;
                    var reportData = SysReportServiceHelper.GetReportData(reportServiceParam);
                    var dataf = reportData.DataSource;
                    List<string> colList = new List<string>();
                    DataTable newDt = new DataTable();
                    foreach (DataColumn item in dataf.Columns)
                    {
                        foreach (var rname in rh)
                        {
                            if (item.ColumnName.ToUpper() == rname.Key.ToUpper())
                            {
                                item.Caption = rname.Caption;
                                colList.Add(item.ColumnName);
                            }
                        }
                    }
                    for (int i = reportData.DataSource.Columns.Count - 1; i >= 0; i--)
                    {
                        int index = colList.IndexOf(reportData.DataSource.Columns[i].ColumnName);
                        if (index != -1)
                        {

                        }
                        else
                        {
                            reportData.DataSource.Columns.Remove(reportData.DataSource.Columns[i].ColumnName);
                        }
                    }
                    newDt = reportData.DataSource;
                    GetNewDt(newDt, baseDataFields, dateFields, comboFields, ctx);
                    newDt = FilteNewDt(newDt, parameter);
                    // 生成 Excel 字节流
                    byte[] excelBytes = DataTableToExcel(newDt);
                    // 发送邮件
                    foreach (var mail in parameter.To)
                    {
                        SendEmailWithAttachment(excelBytes, mail, parameter.ScheduleName);
                    }
                }
            }
            catch (Exception ex)
            {

            }
        }

        private Dictionary<int, IMoveReport> FilteNewDt(Dictionary<int, IMoveReport> rtnDIc, ScheduleParameter parameter)
        {
            // 筛选条件
            string columnName = parameter.fileName;
            string filterValue = parameter.StartDate.StrDate.ToString();
            string filterValue2 = parameter.StartDate.EndDate.ToString();
            if (columnName.IsNullOrEmptyOrWhiteSpace())
            {
                return rtnDIc;
            }
            foreach (var mov in rtnDIc)
            {
                // 原始 DataTable
                DataTable sourceTable = mov.Value.DataSource;
                // 克隆原始表结构（不含数据）
                DataTable filteredTable = sourceTable;

                // 筛选符合条件的行
                DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

                // 将筛选结果导入新表
                foreach (DataRow row in filteredRows)
                {
                    filteredTable.ImportRow(row);
                }
            }
            return rtnDIc;
        }

        private byte[] DataTableToExcel(Dictionary<int, IMoveReport> movList)
        {
            using (var package = new ExcelPackage())
            {
                foreach (var mov in movList)
                {
                    IMoveReport morRe = mov.Value;
                    DataTable dt = morRe.DataSource;
                    var worksheet = package.Workbook.Worksheets.Add($"Sheet{mov.Key + 1}");

                    // 写入列头
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        worksheet.Cells[1, i + 1].Value = dt.Columns[i].Caption;
                        worksheet.Cells[1, i + 1].Style.Font.Bold = true; // 加粗标题
                        worksheet.Cells[1, i + 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                        worksheet.Cells[1, i + 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
                    }

                    // 写入数据
                    for (int row = 0; row < dt.Rows.Count; row++)
                    {
                        for (int col = 0; col < dt.Columns.Count; col++)
                        {
                            worksheet.Cells[row + 2, col + 1].Value = dt.Rows[row][col];
                        }
                    }

                    // 自动调整列宽
                    worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();
                }
                // 返回 Excel 文件的字节流
                return package.GetAsByteArray();
            }
        }

        private void GetMovNewDt(Dictionary<int, IMoveReport> mov, List<BaseDataField> baseDataFields, List<DateField> dateFields, List<ComboField> comboFields, Context ctx)
        {
            foreach (IMoveReport movdata in mov.Values)
            {
                DataTable newDt = movdata.DataSource;
                foreach (BaseDataField field in baseDataFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                object originalValue = row[columnName];
                                if (originalValue != DBNull.Value && originalValue != null)
                                {
                                    var lookObj = field.LookUpObject;
                                    string formId = lookObj.FormId;
                                    string rValue = row[field.Key].ToString();
                                    // 修改列内容
                                    row[tempColumnName] = GetNewValue(rValue, formId, ctx);
                                    // 使用 Convert.ChangeType 进行安全转换
                                    //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                                }
                                else
                                {
                                    row[tempColumnName] = DBNull.Value;  // 处理空值
                                }
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
                foreach (DateField field in dateFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                DateTime originalValue = (DateTime)row[columnName];
                                row[tempColumnName] = originalValue.ToShortDateString();
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
                foreach (ComboField field in comboFields)
                {
                    string columnName = field.Key;
                    Type newType = typeof(string);
                    if (newDt.Columns.Contains(columnName))
                    {
                        // 保存原列的位置
                        int originalOrdinal = newDt.Columns[columnName].Ordinal;
                        // 1. 创建临时新列（避免名称冲突）
                        string tempColumnName = $"{columnName}_New";
                        DataColumn newColumn = new DataColumn(tempColumnName, newType);
                        newColumn.Caption = field.Name;
                        newDt.Columns.Add(newColumn);
                        // 2. 迁移数据（处理转换异常）
                        foreach (DataRow row in newDt.Rows)
                        {
                            try
                            {
                                // 尝试将原列值转换为新类型
                                object originalValue = row[columnName];
                                if (originalValue != DBNull.Value && originalValue != null)
                                {
                                    var lookObj = field.EnumObject;
                                    string rValue = "";
                                    var iList = lookObj["Items"] as DynamicObjectCollection;
                                    foreach (var item in iList)
                                    {
                                        var str = JsonConvert.SerializeObject(item["Value"]);
                                        string strCaption = item["Caption"].GetString();
                                        if (str == JsonConvert.SerializeObject(originalValue))
                                        {
                                            rValue = strCaption;
                                        }
                                    }

                                    // 修改列内容
                                    row[tempColumnName] = rValue;
                                    // 使用 Convert.ChangeType 进行安全转换
                                    //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                                }
                                else
                                {
                                    row[tempColumnName] = DBNull.Value;  // 处理空值
                                }
                            }
                            catch (Exception ex)
                            {
                                // 自定义错误处理（例如记录日志或设置默认值）
                                //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                                row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                            }
                        }
                        // 3. 删除旧列
                        newDt.Columns.Remove(columnName);
                        // 4. 重命名新列并调整位置（可选）
                        newColumn.ColumnName = columnName;
                        newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                    }
                }
            }
        }

        private IMoveReport GetReportDataNext(Context ctx, int i, BusinessInfo businessInfo, IRptParams rptParam)
        {
            // 更新分页下标
            rptParam.CurrentPosition = i;
            // 查询数据
            MoveReportServiceParameter param = new MoveReportServiceParameter(ctx, businessInfo, Guid.NewGuid().ToString(), rptParam);
            return SysReportServiceHelper.GetListAndReportData(param);
        }

        private DataTable FilteNewDt(DataTable newDt, ScheduleParameter parameter)
        {
            // 原始 DataTable
            DataTable sourceTable = newDt;

            // 筛选条件
            string columnName = parameter.fileName;
            string filterValue = parameter.StartDate.StrDate.ToString();
            string filterValue2 = parameter.StartDate.EndDate.ToString();

            // 克隆原始表结构（不含数据）
            DataTable filteredTable = sourceTable.Clone();

            // 筛选符合条件的行
            DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

            // 将筛选结果导入新表
            foreach (DataRow row in filteredRows)
            {
                filteredTable.ImportRow(row);
            }
            return filteredTable;
        }

        private DataTable GetSqlRptData(Context ctx, FormMetadata rptMetadata, ScheduleParameter parameter)
        {
            DataTable dt = null;
            ISQLReportService service = ServiceFactory.GetSQLReportService(ctx);
            SQLFilterParameter filter = new SQLFilterParameter();
            SysReportForm form = rptMetadata.BusinessInfo.GetForm() as SysReportForm;
            try
            {
                List<FilterSettingItem> sqlKeyValue = new List<FilterSettingItem>();
                string xmlContent = GetxmlString(parameter.SchemeId, ctx);
                // 第一步：XML 反序列化
                var xmlSerializer = new XmlSerializer(typeof(SQLFilterSchemeEntity));
                SQLFilterSchemeEntity entity;
                using (var reader = new StringReader(xmlContent))
                {
                    entity = (SQLFilterSchemeEntity)xmlSerializer.Deserialize(reader);
                }

                // 第二步：JSON 反序列化（关键修正点）
                sqlKeyValue = JsonConvert.DeserializeObject<List<FilterSettingItem>>(entity.SQLFilterSettingJson);

                foreach (var keyword in form.SQLDataSource.KeyWordList)
                {
                    SQLFilterField filterField = new SQLFilterField();
                    filterField.Caption = keyword.Name;
                    filterField.IsAllowInput = keyword.IsAllowInput;
                    filterField.IsMultiSelect = keyword.IsMultiSelect;
                    filterField.KeyWord = keyword.KeyWord;
                    foreach (var sqlr in sqlKeyValue)
                    {
                        if (sqlr.KeyWord == keyword.KeyWord)
                        {
                            SQLFilterRow filterRow = new SQLFilterRow(filterField, sqlr.Value, filterField.Caption, false);
                            filter.SQLFilterRows.Add(filterRow);
                        }
                    }
                }
                SqlReportQueryResult sqlReportQueryResult = service.CreateDirectSqlData(ctx, filter, form.SQLDataSource);

                if (sqlReportQueryResult.DataSource == null)
                {
                    if (sqlReportQueryResult.TableName.IsNullOrEmptyOrWhiteSpace() == false)
                    {
                        dt = DBUtils.ExecuteDataSet(ctx, string.Format("SELECT * FROM {0}", sqlReportQueryResult.TableName)).Tables[0];
                    }
                }
                else
                {
                    dt = sqlReportQueryResult.DataSource;
                }
            }
            catch (Exception ex) { }
            if (dt.Columns.Contains("FIDENTITYID"))
            {
                dt.Columns.Remove("FIDENTITYID");
            }
            // 原始 DataTable
            DataTable sourceTable = dt;

            // 筛选条件
            string columnName = parameter.fileName;
            string filterValue = parameter.StartDate.StrDate.ToString();
            string filterValue2 = parameter.StartDate.EndDate.ToString();

            // 克隆原始表结构（不含数据）
            DataTable filteredTable = sourceTable.Clone();

            // 筛选符合条件的行
            DataRow[] filteredRows = sourceTable.Select($"{columnName} >= '{filterValue}' and {columnName} <= '{filterValue2}' ");

            // 将筛选结果导入新表
            foreach (DataRow row in filteredRows)
            {
                filteredTable.ImportRow(row);
            }

            return filteredTable;
        }

        private string GetxmlString(string schemeId, Context ctx)
        {
            string sql = string.Format(@"/*dialect*/ 
            select FSCHEME from T_BAS_FILTERSCHEME where FSCHEMEID='{0}'  ", schemeId);
            DynamicObjectCollection doc = DBUtils.ExecuteDynamicObject(ctx, sql);
            if (doc.Count > 0)
            {
                return doc[0][0].ToString();
            }
            return "";
        }

        private void GetNewDt(DataTable newDt, List<BaseDataField> baseDataFields, List<DateField> dateFields, List<ComboField> comboFields, Context ctx)
        {
            foreach (BaseDataField field in baseDataFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            object originalValue = row[columnName];
                            if (originalValue != DBNull.Value && originalValue != null)
                            {
                                var lookObj = field.LookUpObject;
                                string formId = lookObj.FormId;
                                string rValue = row[field.Key].ToString();
                                // 修改列内容
                                row[tempColumnName] = GetNewValue(rValue, formId, ctx);
                                // 使用 Convert.ChangeType 进行安全转换
                                //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                            }
                            else
                            {
                                row[tempColumnName] = DBNull.Value;  // 处理空值
                            }
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
            foreach (DateField field in dateFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            DateTime originalValue = (DateTime)row[columnName];
                            row[tempColumnName] = originalValue.ToShortDateString();
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
            foreach (ComboField field in comboFields)
            {
                string columnName = field.Key;
                Type newType = typeof(string);
                if (newDt.Columns.Contains(columnName))
                {
                    // 保存原列的位置
                    int originalOrdinal = newDt.Columns[columnName].Ordinal;
                    // 1. 创建临时新列（避免名称冲突）
                    string tempColumnName = $"{columnName}_New";
                    DataColumn newColumn = new DataColumn(tempColumnName, newType);
                    newColumn.Caption = field.Name;
                    newDt.Columns.Add(newColumn);
                    // 2. 迁移数据（处理转换异常）
                    foreach (DataRow row in newDt.Rows)
                    {
                        try
                        {
                            // 尝试将原列值转换为新类型
                            object originalValue = row[columnName];
                            if (originalValue != DBNull.Value && originalValue != null)
                            {
                                var lookObj = field.EnumObject;
                                string rValue = "";
                                var iList = lookObj["Items"] as DynamicObjectCollection;
                                foreach (var item in iList)
                                {
                                    var str = JsonConvert.SerializeObject(item["Value"]);
                                    string strCaption = item["Caption"].GetString();
                                    if (str == JsonConvert.SerializeObject(originalValue))
                                    {
                                        rValue = strCaption;
                                    }
                                }

                                // 修改列内容
                                row[tempColumnName] = rValue;
                                // 使用 Convert.ChangeType 进行安全转换
                                //row[tempColumnName] = Convert.ChangeType(rValue, newType);
                            }
                            else
                            {
                                row[tempColumnName] = DBNull.Value;  // 处理空值
                            }
                        }
                        catch (Exception ex)
                        {
                            // 自定义错误处理（例如记录日志或设置默认值）
                            //Console.WriteLine($"转换失败: 行 {row["ID"]}, 值 '{originalValue}'. 错误: {ex.Message}");
                            row[tempColumnName] = DBNull.Value;  // 设为空或默认值
                        }
                    }
                    // 3. 删除旧列
                    newDt.Columns.Remove(columnName);
                    // 4. 重命名新列并调整位置（可选）
                    newColumn.ColumnName = columnName;
                    newColumn.SetOrdinal(originalOrdinal); // 直接使用保存的位置
                }
            }
        }

        private object GetNewValue(string rValue, string formId, Context ctx)
        {
            var obj = GetDynamicObjectByFormIdAndId(ctx, formId, rValue);
            string name = obj["name"].ToString();
            return name;
        }

        private DynamicObject GetDynamicObjectByFormIdAndId(Context context, string formId, string fid)
        {
            DynamicObject obj = null;
            FormMetadata meta = MetaDataServiceHelper.GetFormMetaData(context, formId);
            QueryBuilderParemeter queryParam = new QueryBuilderParemeter();
            queryParam.FormId = formId;
            queryParam.FilterClauseWihtKey = string.Format(" {0}='{1}'", meta.BusinessInfo.GetForm().PkFieldName, fid);
            var objs = BusinessDataServiceHelper.Load(context, meta.BusinessInfo.GetDynamicObjectType(), queryParam);
            if (objs.Length > 0) obj = objs.FirstOrDefault();
            return obj;
        }

        private void SaveReportData(Context ctx, ScheduleParameter parameter)
        {
            // 读取账表数据（存货收发存汇总表）
            var reportData = GetReportData(ctx, parameter);
        }

        private object GetReportData(Context ctx, ScheduleParameter parameter)
        {
            var metaDataService = new MetaDataService();
            var filterMetadata = new CommonFilterService().GetFilterMetaData(ctx, ""); //加载过滤元数据。
            var reportMetadata = (FormMetadata)metaDataService.Load(ctx, parameter.RptFormId); //加载账表元数据
            var fileList = reportMetadata.BusinessInfo.Elements;
            var reportFilterMetadata = (FormMetadata)metaDataService.Load(ctx, parameter.RptFilterFormId); //加载账表的过滤窗体的元数据。
            var reportFilterServiceProvider = reportFilterMetadata.BusinessInfo.GetForm().GetFormServiceProvider();
            var model = new SysReportFilterModel();
            model.SetContext(ctx, reportFilterMetadata.BusinessInfo, reportFilterServiceProvider);
            model.FormId = reportFilterMetadata.BusinessInfo.GetForm().Id;
            model.FilterObject.FilterMetaData = filterMetadata;
            model.InitFieldList(reportMetadata, reportFilterMetadata);
            model.GetSchemeList();
            var entity = model.Load(parameter.SchemeId);
            var dyn = DeserializeCustomFilter(reportFilterMetadata.BusinessInfo, entity.CustomFilterSetting);
            model.DataObject = dyn;
            var filter = model.GetFilterParameter();
            IRptParams rptParams = new RptParams();
            rptParams.FormId = reportMetadata.BusinessInfo.GetForm().Id;
            rptParams.FilterParameter = filter;
            rptParams.FilterFieldInfo = model.FilterFieldInfo;
            rptParams.ParameterData = GetUserParamters(ctx, reportMetadata.BusinessInfo);
            rptParams.IsOnlyQuerySumData = GetOnlyDspSumData(rptParams.ParameterData);
            rptParams.CurrentPosition = 0;
            rptParams.StartRow = 1;
            rptParams.EndRow = int.MaxValue;
            var rh = rptParams.FilterParameter.ColumnInfo;
            var param = new ReportServiceParameter(ctx, reportMetadata.BusinessInfo, Guid.NewGuid().ToString(), rptParams);
            var reportData = new SysReportService().GetReportData(param);
            var dataf = reportData.DataSource;
            List<string> colList = new List<string>();
            DataTable newDt = new DataTable();
            foreach (DataColumn item in dataf.Columns)
            {
                foreach (var rname in rh)
                {
                    if (item.ColumnName.ToUpper() == rname.Key.ToUpper())
                    {
                        item.Caption = rname.Caption;
                        colList.Add(item.ColumnName);
                    }
                }
            }
            for (int i = reportData.DataSource.Columns.Count - 1; i >= 0; i--)
            {
                int index = colList.IndexOf(reportData.DataSource.Columns[i].ColumnName);
                if (index != -1)
                {

                }
                else
                {
                    reportData.DataSource.Columns.Remove(reportData.DataSource.Columns[i].ColumnName);
                }
            }
            newDt = reportData.DataSource;
            // 生成 Excel 字节流
            byte[] excelBytes = DataTableToExcel(newDt);
            // 发送邮件
            foreach (var mail in parameter.To)
            {
                SendEmailWithAttachment(excelBytes, mail, parameter.ScheduleName);
            }
            return reportData;
        }

        private void SendEmailWithAttachment(byte[] excelData, string recipientEmail, string scheduleName)
        {
            try
            {
                //var fromAddress = new MailAddress("mes@bpw.cn", "Data Report");
                var fromAddress = new MailAddress("it@dna-group.com", "Data Report");
                var toAddress = new MailAddress(recipientEmail);

                using (var message = new MailMessage(fromAddress, toAddress))
                {
                    message.Subject = scheduleName;
                    message.Body = "请查收附件中的 Excel 文件。";

                    // 添加附件
                    var stream = new MemoryStream(excelData);
                    var attachment = new Attachment(stream, scheduleName + ".xlsx", MediaTypeNames.Application.Octet);
                    message.Attachments.Add(attachment);

                    // 配置 SMTP
                    using (var smtp = new SmtpClient("smtp.qiye.aliyun.com", 25))
                    {
                        smtp.Credentials = new NetworkCredential("it@dna-group.com", "Dna111222");
                        smtp.EnableSsl = false; // 根据 SMTP 服务器要求启用 SSL
                        smtp.Send(message);
                    }
                }

                Console.WriteLine("邮件发送成功！");
            }
            catch (Exception ex)
            {
                Console.WriteLine($"发送失败: {ex.Message}");
            }
        }

        private byte[] DataTableToExcel(DataTable dt)
        {
            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("Sheet1");

                // 写入列头
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    worksheet.Cells[1, i + 1].Value = dt.Columns[i].Caption;
                    worksheet.Cells[1, i + 1].Style.Font.Bold = true; // 加粗标题
                    worksheet.Cells[1, i + 1].Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
                    worksheet.Cells[1, i + 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.LightGray);
                }

                // 写入数据
                for (int row = 0; row < dt.Rows.Count; row++)
                {
                    for (int col = 0; col < dt.Columns.Count; col++)
                    {
                        worksheet.Cells[row + 2, col + 1].Value = dt.Rows[row][col];
                    }
                }

                // 自动调整列宽
                worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();

                // 返回 Excel 文件的字节流
                return package.GetAsByteArray();
            }
        }

        private bool GetOnlyDspSumData(DynamicObject userParameterData)
        {
            var result = false;
            if (userParameterData != null && userParameterData.DynamicObjectType.Properties.ContainsKey(KeyConst.FDSPSUMDATA_KEY))
            {
                result = (bool)userParameterData[KeyConst.FDSPSUMDATA_KEY];
            }
            return result;
        }

        private DynamicObject GetUserParamters(Context ctx, BusinessInfo reportBusinessInfo)
        {
            string formId = reportBusinessInfo.GetForm().ParameterObjectId;
            if (formId == null || formId.Trim().Length == 0)
            {
                formId = FormIdConst.BOS_ReportUserParameter;
            }
            var formMetadata = (FormMetadata)new MetaDataService().Load(ctx, formId);
            return new UserParameterService().Load(ctx, formMetadata.BusinessInfo, ctx.UserId, reportBusinessInfo.GetForm().Id);
        }

        private DynamicObject DeserializeCustomFilter(BusinessInfo businessInfo, string xml)
        {
            var binder = new DynamicObjectDcxmlBinder(businessInfo);
            binder.OnlyDbProperty = false;
            var target = new DcxmlSerializer(binder);
            binder.Culture = CultureInfo.InvariantCulture;
            target.ColloctionIgnorePKValue = true;
            var obj = (DynamicObject)target.DeserializeFromString(xml);
            return obj;
        }
    }

    /// <summary>
    /// 列表引出服务
    /// </summary>
    public class ListExportService
    {

        #region var

        #region const

        // 引出设置标识
        private const string STRSETUPINFO = "ExportSetting";

        #endregion

        // 引出文件类型
        private SaveFileType _fileType = SaveFileType.XLS;
        private string _outServicePath = "";
        private string _filePath = "";
        private string _directioy = "";

        /// <summary>
        /// 待执行引出取数操作的视图
        /// </summary>
        private IDynamicFormView view;

        #endregion

        public ListExportService(IDynamicFormView listView)
        {
            this.view = listView;
        }

        /// <summary>
        /// 创建列表引出文件
        /// </summary>
        /// <returns></returns>
        public string ExportData()
        {
            Logger.Info("JAC", view.BillBusinessInfo.GetForm().Name + "列表引出开始");
            InitVariable();
            using (ExcelOperation helper = new ExcelOperation(view))
            {
                var count = BOSConst.DefaultAllRowCount;
                //var listJson = ((IListViewService)view).GetExportData(0, count, PermissionConst.Export, false);
                var listJson = ((ISysReportViewService)view).GetData(0, count);
                if (!listJson.ContainsKey("rows"))
                {
                    throw new KDException("###", string.Format("您没有“{0}”的“引出”权限！", view.BillBusinessInfo.GetForm().Name));
                }

                var rows = (JSONArray)listJson["rows"];
                if (rows.Count == 0)
                {
                    //throw new KDException("###", "没有可以引出的数据，请确认在查询的组织范围内有引出当前单据的权限。");
                    return string.Empty;
                }

                var ListField = new List<ExcelField>();
                var dt = new DataTable();
                var columnIndexs = new List<int>();
                var exportTypeList = new List<ExportDataType>();
                GetListExportConfigInfo(ListField, dt, columnIndexs, exportTypeList);
                GetTable(ref dt, columnIndexs, rows, exportTypeList);
                int maxrowcount = GetBillCountPerExportFile();
                List<string> columnsNames = ListField.Select(p => p.Caption).ToList();
                if (dt.Rows.Count > maxrowcount)
                {
                    using (ExcelOperation helper2 = new ExcelOperation(view))
                    {
                        helper2.BeginExport();
                        //此处构建dataset,使用通用接口来做拆分大量数据
                        using (DataSet ds = ReBuildExportListData(dt, columnsNames, maxrowcount, null))
                        {
                            dt.Dispose();
                            helper2.DateSetToExcel(ds, false);
                            //按用户配置的引出文件类型引出文件
                            helper2.EndExport(_filePath, _fileType);
                        }

                        //helper2.DownLoadFile(OutServicePath);
                    }
                }
                else
                {
                    helper.BeginExport();
                    helper.FillColumnName(columnsNames);
                    helper.ExportToFile(dt);
                    //按用户配置的引出文件类型引出文件
                    helper.EndExport(_filePath, _fileType);
                    // helper.DownLoadFile(OutServicePath);
                }
            }

            Logger.Info("JAC", view.BillBusinessInfo.GetForm().Name + "列表引出成功：" + _filePath);
            return _filePath;
        }

        /// <summary>
        /// 发送邮件
        /// 参考：https://vip.kingdee.com/article/131834587734451200
        /// </summary>
        public void SendMail(string filePath)
        {
            var sendMailService = new SendMailService();
            // 获取邮件服务器信息，发件人信息
            //var emailInfo = sendMailService.GetEmailMessageInfoByUserId(view.Context, view.Context.UserId);
            EmailMessageInfo emailInfo = new EmailMessageInfo();
            //设置邮件服务器
            SetMailServer(emailInfo);
            // 设置邮件标题
            emailInfo.Subject = "采购订单列表引出数据";
            // 设置邮件内容
            emailInfo.Body = string.Format("单据名称：采购订单<br>导出人：{0}<br>导出时间：{1}", view.Context.UserName, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            // 设置邮件接收人
            emailInfo.To = new List<string>();
            emailInfo.To.Add("49872850@qq.com");
            // 设置邮件抄送人
            //emailInfo.Cc = new List<string>();
            //emailInfo.Cc.Add("999999@qq.com");
            // 设置邮件附件信息
            if (!string.IsNullOrWhiteSpace(filePath) && File.Exists(filePath))
            {
                emailInfo.Attachments = new List<string>();
                emailInfo.Attachments.Add(_filePath);
            }
            else
            {
                emailInfo.Body += "<br>本次操作未查询到满足条件的数据，无引出文件。";
            }

            MailUtils.Sendmail(emailInfo);
            Logger.Info("JAC", view.BillBusinessInfo.GetForm().Name + "邮件发送成功：" + _filePath);
        }

        private void SetMailServer(EmailMessageInfo emailInfo)
        {
            emailInfo.EnableSSL = false;
            emailInfo.From = "mes@bpw.cn";
            emailInfo.FromName = "金蝶云星空自动邮件";
            emailInfo.IsBodyHtml = true;
            emailInfo.IsMailBCC = false;
            emailInfo.Password = "bpwmz2022";
            emailInfo.Protocol = EmailProtocol.POP3;
            emailInfo.PwdDecode = true;
            emailInfo.SendType = EmailSendType.Default;
            emailInfo.SmtpHost = "61.143.205.219";
            emailInfo.SmtpPort = 25;
            emailInfo.UserName = "mes@bpw.cn";
        }

        private void InitVariable()
        {
            _fileType = GetSaveType(view.BillBusinessInfo.GetForm().Id);
            _directioy = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, KeyConst.TEMPFILEPATH);
            string fileName = string.Format("{0}_{1}", view.BillBusinessInfo.GetForm().Name, DateTime.Now.ToString("yyyyMMddHHmmssff"));
            fileName = PathUtils.GetValidFileName(fileName);
            //按用户设置的引出文件类型引出对应的文件,默认是Excel2003（.xls）
            if (this._fileType == SaveFileType.XLSX)
            {
                fileName += ".xlsx";
            }
            else
            {
                fileName += ".xls";
            }

            _outServicePath = PathUtils.GetServerPath(KeyConst.TEMPFILEPATH, PathUtils.UrlEncode(fileName));
            _filePath = PathUtils.GetPhysicalPath(KeyConst.TEMPFILEPATH, fileName);
            InitDirectioy();
        }

        /// <summary>
        /// 生成列表引出配置信息
        /// </summary>
        /// <param name="ListField"></param>
        /// <param name="dt"></param>
        /// <param name="columnIndexs"></param>
        /// <param name="exportTypeList"></param>
        private void GetListExportConfigInfo(List<ExcelField> ListField, DataTable dt, List<int> columnIndexs, List<ExportDataType> exportTypeList)
        {
            var model = view.Model;
            ListHeader header = ((IListModel)view.Model).Header;
            //ReportHeader header = ((ISysReportModel)view.Model).ReportHeader;
            if (header != null && header.GetChildCount() > 0)
            {
                for (int i = 0; i < header.GetChilds().Count; i++)
                {
                    ReportHeader h = (ReportHeader)header.GetChilds()[i];
                    if (h.Visible)
                    {
                        ListField.Add(
                            new ExcelField()
                            {
                                FieldName = h.FieldName,
                                Caption = h.Caption
                            });
                        if (h.FieldAppearance is ImageFieldAppearance)
                        {
                            dt.Columns.Add(h.FieldName, typeof(Byte[]));
                            exportTypeList.Add(ExportDataType.DatabaseImage);
                        }
                        else if (h.FieldAppearance is ImageFileServerFieldAppearance
                                 || h.FieldAppearance is PictureFieldAppearance)
                        {
                            dt.Columns.Add(h.FieldName, typeof(Byte[]));
                            exportTypeList.Add(ExportDataType.FileServerImage);
                        }
                        else
                        {
                            dt.Columns.Add(h.FieldName);
                            exportTypeList.Add(ExportDataType.CommonData);
                        }

                        columnIndexs.Add(i);
                    }
                }
            }
        }

        private void GetTable(ref System.Data.DataTable dt, List<int> columnIndexs, JSONArray rows, List<ExportDataType> exportTypeList)
        {
            bool allowdSOSeq = false;
            if (view.Model.ParameterData != null && view.Model.ParameterData.DynamicObjectType.Properties.ContainsKey(KeyConst.FALLOWDSPSEQ_KEY))
            {
                Boolean.TryParse(view.Model.ParameterData[KeyConst.FALLOWDSPSEQ_KEY].ToString(), out allowdSOSeq);
            }

            for (int i = 0; i < rows.Count; i++)
            {
                DataRow newRow = dt.NewRow();
                for (int j = 0; j < columnIndexs.Count; j++)
                {
                    int colIndex = columnIndexs[j];
                    if (allowdSOSeq)
                    {
                        //显示序号，列索引需要增加1
                        colIndex = columnIndexs[j] + 1;
                    }

                    if (exportTypeList[j] == ExportDataType.CommonData)
                    {
                        newRow[j] = ((JSONArray)rows[i])[colIndex];
                    }
                    else if (exportTypeList[j] == ExportDataType.DatabaseImage)
                    {
                        newRow[j] = Convert.FromBase64String(((JSONArray)rows[i])[colIndex].ToString());
                    }
                    else if (exportTypeList[j] == ExportDataType.FileServerImage)
                    {
                        string downloadUrl = ((JSONArray)rows[i])[colIndex].ToString();
                        Regex regex = new Regex(@"(?<=fileId=)[\w]+", RegexOptions.IgnoreCase);
                        string fileId = regex.Match(downloadUrl).GetString();

                        byte[] byteData = GetImageByte(view.Context, fileId);
                        newRow[j] = byteData;
                    }
                }

                dt.Rows.Add(newRow);
            }
        }

        /// <summary>
        /// 获取图片字节流数据
        /// </summary>
        private byte[] GetImageByte(Context ctx, string fileId)
        {
            if (!string.IsNullOrWhiteSpace(fileId))
            {
                try
                {
                    TFileInfo tFile = new TFileInfo { FileId = fileId, CTX = ctx };
                    return new UpDownloadService().GetFileData(tFile);
                }
                catch
                {
                    return null;
                }
            }

            return null;
        }

        /// <summary>
        /// 获取配置文件中每个引出文件容纳的最大单据数
        /// </summary>
        /// <returns></returns>
        private int GetBillCountPerExportFile()
        {
            int iBillCountPerExportFile = KDConfiguration.Current.BillCountPerExportFile;
            if (iBillCountPerExportFile > 100000)
            {
                return 100000;
            }

            return iBillCountPerExportFile;
        }

        /// <summary>
        /// 初始化引出文件存放的文件夹，没有则创建
        /// </summary>
        private void InitDirectioy()
        {
            string directioy = _directioy;
            if (Directory.Exists(directioy) == false)
            {
                Directory.CreateDirectory(directioy);
            }
        }

        /// <summary>
        /// 重新构建列表引出的数据，取消掉所有的格式
        /// </summary>
        /// <returns></returns>
        private DataSet ReBuildExportListData(DataTable dt, List<string> columnnames, int maxrowcount, List<ListHeader> listHeaders)
        {
            DataSet ds = new DataSet();
            DataTable subdt;
            if (listHeaders != null)
            {
                subdt = new System.Data.DataTable();
                for (int i = 0; i < listHeaders.Count; i++)
                {
                    string fieldName = listHeaders[i].FieldName;
                    if (dt.Columns.Contains(fieldName))
                    {
                        DataColumn column = new DataColumn(fieldName, dt.Columns[fieldName].DataType);
                        subdt.Columns.Add(column);
                    }
                }
            }
            else
            {
                subdt = dt.Clone();
            }

            int count = 1;
            string tablename = view.BillBusinessInfo.GetForm().Name;
            subdt.TableName = string.Format("{0}_Part{1}", tablename, count);
            int idx = 0;
            foreach (DataRow dr in dt.Rows)
            {
                if (idx == 0)
                {
                    DataRow rowname = subdt.NewRow();
                    for (int i = 0; i < columnnames.Count(); i++)
                    {
                        rowname[i] = columnnames[i];
                    }

                    subdt.Rows.Add(rowname);
                }

                DataRow row = subdt.NewRow();
                foreach (DataColumn col in subdt.Columns)
                {
                    row[col] = dr[col.ColumnName];
                }

                subdt.Rows.Add(row);
                idx++;
                if (idx == maxrowcount)
                {
                    idx = 0;
                    ds.Tables.Add(subdt);

                    subdt = subdt.Clone();
                    count++;
                    subdt.TableName = string.Format("{0}_Part{1}", tablename, count);
                }
            }

            if (subdt.Rows.Count > 0)
            {
                ds.Tables.Add(subdt);
            }

            return ds;
        }

        /// <summary>
        /// 获取用户配置的引出文件格式
        /// </summary>
        /// <param name="formId"></param>
        /// <returns></returns>
        protected SaveFileType GetSaveType(string formId)
        {
            var info = Kingdee.BOS.ServiceHelper.UserParamterServiceHelper.Load(this.view.Context, STRSETUPINFO + formId.ToUpperInvariant().GetHashCode().ToString(), this.view.Context.UserId);
            if (!string.IsNullOrWhiteSpace(info) && info != "<Root />")
            {
                JSONArray jsonArray = new JSONArray(info);
                string fileTypeValue = GetValuebyKey(jsonArray, "filetype");
                if (!fileTypeValue.IsNullOrEmpty())
                {
                    SaveFileType type;
                    if (Enum.TryParse(fileTypeValue, out type))
                    {
                        return type;
                    }
                }
            }

            return SaveFileType.XLSX;
        }

        /// <summary>
        /// JSON数组中按键值取数
        /// </summary>
        /// <param name="jsonArray"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        private string GetValuebyKey(JSONArray jsonArray, string key)
        {
            string result = string.Empty;
            if (jsonArray == null)
            {
                return result;
            }

            for (int i = 0; i < jsonArray.Count; i++)
            {
                Dictionary<string, object> obj = jsonArray[i] as Dictionary<string, object>;
                if (obj != null && obj["key"] != null && obj["key"].ToString() == key)
                {
                    result = ObjectUtils.Object2String(obj["value"]);
                    break;
                }
            }

            return result;
        }
    }

    /// <summary>
    /// 列表视图构建器
    /// </summary>
    public class ListViewBuilder
    {
        /// <summary>
        /// 创建列表打印查询视图
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="formId"></param>
        /// <param name="schemeId"></param>
        /// <returns></returns>
        public IDynamicFormView CreateListPrintView(Context ctx, string formId, string schemeId)
        {
            // 构建报表窗体打开参数, 
            var formMetaData = (FormMetadata)new MetaDataService().Load(ctx, formId);
            // ShowParameter
            SysReportShowParameter showParam = new SysReportShowParameter();
            //var showParam = new ListShowParameter();
            showParam.FormId = formId;
            showParam.PageId = Guid.NewGuid().ToString();
            var paraObj = showParam.CreateWebParams();
            // OpenParameter
            var dynamicFormMetaDataService = new DynamicFormMetaDataService();
            var sessionManager = new SessionManager();
            dynamicFormMetaDataService.SetContext(sessionManager, ctx);
            dynamicFormMetaDataService.FormMetaData = formMetaData;
            dynamicFormMetaDataService.GetDynamicFormConfig(paraObj);
            var openParam = sessionManager.Get<DynamicFormOpenParameter>(showParam.PageId, FormConst.OPEN_PARAM);
            openParam.SetCustomParameter("SessionManager", sessionManager);
            // 创建视图
            //var rptView = new ListPrintWebService(schemeId, null, null);
            var rptView = new SysReportPrintWebService(schemeId, null);
            //var aa = new ReportPerPages("aa", new ReportTitles());
            // 初始化视图
            // 获取简单账表资源服务提供器
            IResourceServiceProvider provider = GetSysReportServiceProvider();

            //var provider = GetListServiceProvider(openParam);
            rptView.Initialize(openParam, provider);
            rptView.LoadData();
            return rptView;
        }

        private IResourceServiceProvider GetSysReportServiceProvider()
        {
            FormServiceProvider provider = new FormServiceProvider();
            Type type = TypesContainer.GetOrRegister("Kingdee.BOS.Web.Report.SysReportView,Kingdee.BOS.Web");
            provider.Add(typeof(IDynamicFormView), Activator.CreateInstance(type));
            provider.Add(typeof(DynamicFormViewPlugInProxy), new SysReportViewPlugInProxy());
            provider.Add(typeof(DynamicFormModelPlugInProxy), new SysReportModelPlugInProxy());
            type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.Report.SysReportModel,Kingdee.BOS.Model");
            provider.Add(typeof(IDynamicFormModelService), Activator.CreateInstance(type));
            type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.ReportFilter.SysReportFilterModel,Kingdee.BOS.Model");
            provider.Add(typeof(ISysReportFilterModelService), Activator.CreateInstance(type));
            type = TypesContainer.GetOrRegister("Kingdee.BOS.Business.DynamicForm.DefaultValue.DefaultValueCalculator,Kingdee.BOS.Business.DynamicForm");
            provider.Add(typeof(IDefaultValueCalculator), Activator.CreateInstance(type));
            // 注册IDBModelService
            type = TypesContainer.GetOrRegister("Kingdee.BOS.Business.DynamicForm.DBModel.DBModelService,Kingdee.BOS.Business.DynamicForm");
            provider.Add(typeof(IDBModelService), Activator.CreateInstance(type));
            return provider;
        }

        /// <summary>
        /// 获取报表服务提供者
        /// </summary>
        /// <returns></returns>
        private IResourceServiceProvider GetListServiceProvider(DynamicFormOpenParameter param)
        {
            var provider = new FormServiceProvider();
            //provider.Add(typeof(IDynamicFormView), CreateListView(param));
            provider.Add(typeof(ISysReportView), CreateListView(param));
            //provider.Add(typeof(DynamicFormViewPlugInProxy), new ListViewPlugInProxy());
            provider.Add(typeof(DynamicFormViewPlugInProxy), new DynamicFormViewPlugInProxy());
            //provider.Add(typeof(DynamicFormModelPlugInProxy), new ListModelPlugInProxy());
            provider.Add(typeof(DynamicFormModelPlugInProxy), new DynamicFormModelPlugInProxy());
            //provider.Add(typeof(IDynamicFormModelService), GetListModel(param));
            provider.Add(typeof(ISysReportModelService), GetListModel(param));
            //provider.Add(typeof(IListFilterModelService), GetListFilterModel());
            provider.Add(typeof(ISysReportFilterModelService), GetListFilterModel());
            var type = TypesContainer.GetOrRegister("Kingdee.BOS.Business.DynamicForm.DefaultValue.DefaultValueCalculator,Kingdee.BOS.Business.DynamicForm");
            //var type = TypesContainer.GetOrRegister("Kingdee.BOS.Web.Utils.WebServiceViewBuilder,Kingdee.BOS.Web");
            provider.Add(typeof(IDefaultValueCalculator), Activator.CreateInstance(type));
            // 注册IDBModelService
            type = TypesContainer.GetOrRegister("Kingdee.BOS.Business.DynamicForm.DBModel.DBModelService,Kingdee.BOS.Business.DynamicForm");
            //type = TypesContainer.GetOrRegister("Kingdee.BOS.Web.Utils.WebServiceViewBuilder,Kingdee.BOS.Web");
            provider.Add(typeof(IDBModelService), Activator.CreateInstance(type));
            return provider;
        }

        /// <summary>
        /// 获取视图
        /// </summary>
        /// <returns></returns>
        private IDynamicFormView CreateListView(DynamicFormOpenParameter param)
        {
            var form = param.FormMetaData.BusinessInfo.GetForm();
            if (form.FormGroups != null && form.FormGroups.Count > 0)
            {
                //return new TreeListView();
                return new SysReportView();
            }
            else
            {
                //return new ListView();
                return new SysReportView();
            }
        }

        /// <summary>
        /// 获取视图模型
        /// </summary>
        /// <returns></returns>
        private IDynamicFormModelService GetListModel(DynamicFormOpenParameter param)
        {
            var form = param.FormMetaData.BusinessInfo.GetForm();
            if (form.FormGroups != null && form.FormGroups.Count > 0)
            {
                //Kingdee.BOS.Web.Utils.WebServiceViewBuilder,Kingdee.BOS.Web
                //var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.List.TreeListModel,Kingdee.BOS.Model");
                var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.Report.SysReportModel,Kingdee.BOS.Model");
                //return (IDynamicFormModelService)Activator.CreateInstance(type);
                return (ISysReportModelService)Activator.CreateInstance(type);
            }
            else
            {
                //var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.List.ListModel,Kingdee.BOS.Model");
                var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.Report.SysReportModel,Kingdee.BOS.Model");
                //return (IDynamicFormModelService)Activator.CreateInstance(type);
                return (ISysReportModelService)Activator.CreateInstance(type);
            }
        }

        /// <summary>
        /// 创建过滤条件模型
        /// </summary>
        /// <returns></returns>
        private ISysReportFilterModel GetListFilterModel()
        {
            //Kingdee.BOS.Web.Utils.WebServiceViewBuilder
            //var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.ListFilter.ListFilterModel,Kingdee.BOS.Model");
            var type = TypesContainer.GetOrRegister("Kingdee.BOS.Model.ReportFilter.SysReportFilterModel,Kingdee.BOS.Model");
            //return (IListFilterModelService)Activator.CreateInstance(type);
            return (ISysReportFilterModel)Activator.CreateInstance(type);
        }
    }
}
